package com.android.fragmentdemo.defineviews
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import com.android.fragmentdemo.R
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

class LooperRollCircleView @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null
) : View(context, attributeSet),CoroutineScope by MainScope() {

    private val defaultWidth = resources.getDimension(R.dimen.dp_60).toInt()
    private val defaultHeight = resources.getDimension(R.dimen.dp_10).toInt()

    private val defaultRadius = resources.getDimension(R.dimen.dp_5)

    private var normalColor = resources.getColor(R.color.color_673ab7)
    private var highlightColor = resources.getColor(R.color.color_B128C9)

    private var mWidth = 0
    private var mHeight = 0

    private var changeColor = false

    private var currentCircle: Circle = Circle.None

    private var job: Job? = null

    private val leftPaint by lazy {
        Paint().apply {
            isAntiAlias = true
            isDither = true
            style = Paint.Style.FILL
            color = normalColor
        }
    }

    private val middlePaint by lazy {
        Paint().apply {
            isAntiAlias = true
            isDither = true
            style = Paint.Style.FILL
            color = normalColor
        }
    }

    private val rightPaint by lazy {
        Paint().apply {
            isAntiAlias = true
            isDither = true
            style = Paint.Style.FILL
            color = normalColor
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        mWidth = when (MeasureSpec.getMode(widthMeasureSpec)) {
            MeasureSpec.EXACTLY -> {
                MeasureSpec.getSize(widthMeasureSpec)
            }
            else -> {
                defaultWidth
            }
        } - paddingStart - paddingEnd

        mHeight = when (MeasureSpec.getMode(heightMeasureSpec)) {
            MeasureSpec.EXACTLY -> {
                MeasureSpec.getSize(heightMeasureSpec)
            }
            else -> {
                defaultHeight
            }
        } - paddingTop - paddingBottom

        setMeasuredDimension(mWidth, mHeight)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.apply {
            val baseCx = mWidth.toFloat() / 3
            val baseCy = mHeight.toFloat() / 2
            drawCircle(baseCx / 2, baseCy, defaultRadius, leftPaint)
            drawCircle(baseCx / 2 + baseCx, baseCy, defaultRadius, middlePaint)
            drawCircle(baseCx / 2 + + baseCx * 2, baseCy, defaultRadius, rightPaint)
        }
    }

    companion object {
        const val TAG = "LooperRollCircleView"
    }

    fun exeChangeColor() {
        changeColor = true
        job = launch {
            while (changeColor) {
                when (currentCircle) {
                    Circle.LeftCircle -> {
                        leftPaint.color = highlightColor
                        middlePaint.color = normalColor
                        rightPaint.color = normalColor
                        currentCircle = Circle.MiddleCircle
                    }
                    Circle.MiddleCircle -> {
                        leftPaint.color = normalColor
                        middlePaint.color = highlightColor
                        rightPaint.color = normalColor
                        currentCircle = Circle.RightCircle
                    }
                    Circle.RightCircle -> {
                        leftPaint.color = normalColor
                        middlePaint.color = normalColor
                        rightPaint.color = highlightColor
                        currentCircle = Circle.LeftCircle
                    }
                    else -> {
                        currentCircle = Circle.LeftCircle
                    }
                }
                invalidate()
                delay(250)
            }
        }
        job?.start()
    }

    fun stopChangeColor() {
        changeColor = false
        currentCircle = Circle.None
        job?.cancel()
    }

    sealed class Circle {
        data object LeftCircle : Circle()
        data object MiddleCircle : Circle()
        data object RightCircle : Circle()
        data object None : Circle()
    }
}